home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DDJMAG / DDJ9207.ZIP / FILTER.ZIP / VIEWER.C < prev    next >
C/C++ Source or Header  |  1992-01-28  |  18KB  |  579 lines

  1. /****************************************************************************
  2.  
  3.     FILE   : Viewer.c
  4.  
  5.     PURPOSE: Graphics file viewer
  6.  
  7.     FUNCTIONS:
  8.  
  9.     WinMain() - calls initialization function, processes message loop
  10.     MainWndProc() - processes messages
  11.     ImportFile() - Converts graphics file to Windows Metafile
  12.     GetExtFilter() - Determines correct filter for chosen file
  13.     GetPrinterIC() - Determines current printer
  14.     AboutDlgProc() - processes messages for "About" dialog box
  15.  
  16.     COMMENTS:
  17.  
  18. ⌐ 1992, Evangelo Prodromou.  All rights reserved.
  19. ****************************************************************************/
  20.  
  21. /* include the general Windows header and the header for this application. */
  22.  
  23. #include "windows.h"                
  24. #include "viewer.h"
  25.  
  26. /* These strings are used repeatedly. */
  27.  
  28. char    szAppName[ ]            = "GraphicViewer";        
  29. char    szClassName[ ]          = "ViewerWClass";
  30. char    szMenuName[ ]           = "ViewerMenu";
  31.  
  32. char    szString[ STRINGSIZE ];          /* General use string. */
  33. char    szFilter[ IBMFNSIZE ];  /* full path name of import filter. */
  34.  
  35. /* Info struct of the imported metafile. */
  36.  
  37. PICTINFO PictInfo = { NULL,0,0,0,0,0 };
  38.  
  39. /* Spec struct for file to import. */
  40.  
  41. FILESPEC FileSpec = { 0,0,0,0,0,0L,NULL };
  42.  
  43. HANDLE  hInst;                    /* Handle for this instance. */
  44.  
  45. /***************************************************************************
  46.  
  47. FUNCTION: WinMain
  48. PURPOSE:  Entrance point of application
  49.  
  50. ARGS:     hInstance     : handle to this instance.
  51.       hPrevInstance : handle to previous instance of the application.
  52.       lpCmdLine     : command line string
  53.       nCmdShow      : show full or iconic? Passed to ShowWindow()
  54.    
  55. COMMENTS: If no previous instance, registers the window class.
  56.       Saves this instance handle as a global variable.  
  57.       Parses command line for a file name to view.  
  58.       Creates window for this instance. 
  59.       Shows the window.
  60.       Takes and translates messages from the message loop and passes
  61.          them on to MainWndProc().
  62.  
  63. ***************************************************************************/
  64. int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
  65.             LPSTR lpCmdLine, int nCmdShow)
  66. {
  67.     MSG             msg;    /* Windows message structure */                                 
  68.     WNDCLASS        wc;     /* Window class structure. */
  69.     HWND            hMain;  /* handle to main window.  */
  70.  
  71. /* If there is no previous instance of the application, fill in the 
  72. ** window class structure and register the class. */
  73.  
  74.     if (!hPrevInstance)
  75.     {       
  76.         wc.style =              NULL;                    
  77.         wc.lpfnWndProc =        MainWndProc;       
  78.         wc.cbClsExtra =         0;                  
  79.         wc.cbWndExtra =         0;                  
  80.         wc.hInstance =          hInstance;           
  81.         wc.hIcon =              LoadIcon(NULL, IDI_APPLICATION);
  82.         wc.hCursor =            LoadCursor(NULL, IDC_ARROW);
  83.         wc.hbrBackground =      GetStockObject(WHITE_BRUSH); 
  84.         wc.lpszMenuName =       (LPSTR) szMenuName;   
  85.         wc.lpszClassName =      (LPSTR) szClassName; 
  86.  
  87.         if (!RegisterClass(&wc))
  88.             return FALSE;
  89.     }       
  90.  
  91. /* Save the instance handle as a global variable. */
  92.  
  93.     hInst = hInstance;
  94.          
  95. /* Copy the command line argument to the filename field of FileSpec. */
  96.  
  97.     lstrcpy( FileSpec.fullName,  lpCmdLine );
  98.     
  99. /* Create the main window (will send WM_CREATE to the MainWndProc). */
  100.  
  101.     hMain = CreateWindow( szClassName, szAppName,         
  102.             WS_OVERLAPPEDWINDOW,            
  103.             CW_USEDEFAULT, CW_USEDEFAULT,                  
  104.             CW_USEDEFAULT, CW_USEDEFAULT,                  
  105.             NULL, NULL, hInstance, NULL );
  106.  
  107.     if (!hMain)
  108.         return (FALSE);
  109.  
  110. /* Show the window and update it ( sends WM_PAINT to MainWndProc ). */
  111.  
  112.     ShowWindow(hMain, nCmdShow);  
  113.     UpdateWindow(hMain);
  114.  
  115. /* Get window messages for this instance and send them to the MainWndProc. 
  116. ** Loops until WM_QUIT message is received. */
  117.  
  118.     while ( GetMessage( &msg,NULL,NULL,NULL )  )            
  119.     {
  120.         TranslateMessage( &msg );    
  121.         DispatchMessage( &msg );     
  122.     }
  123.     return ( msg.wParam );       
  124. }
  125.  
  126. /***************************************************************************
  127.  
  128. FUNCTION: MainWndProc
  129. PURPOSE:  Processes messages for main window
  130.  
  131. ARGS:     hWnd          : handle to main window
  132.       message       : windows message
  133.       wParam        : extra message info
  134.       lParam        : extra message info
  135.    
  136. MESSAGES: WM_CREATE     : If a file was specified on the command line, gets
  137.               the correct filter by extension, and tries to
  138.               import it.  If no file specified, or if no matching
  139.               filter is found, asks for a new file.
  140.  
  141.       WM_PAINT      : If a file has been imported, displays the 
  142.               resulting metafile.  Otherwise, passes the message
  143.               to default.
  144.  
  145.       WM_SIZE       : Invalidate whole client area, and repaint.
  146.  
  147.       WM_DESTROY    : Terminates program.
  148.  
  149.       WM_COMMAND    : IDM_ABOUT     : Displays About dialog box.
  150.  
  151. ***************************************************************************/
  152.  
  153. long FAR PASCAL MainWndProc(HWND hWnd, unsigned message, 
  154.                 WORD wParam, LONG lParam)
  155. {
  156.     FARPROC lpProc;               
  157.     BOOL    bError;
  158.     RECT        rc;
  159.  
  160.     switch (message) 
  161.     {
  162.     case WM_CREATE:
  163.  
  164.         /* Assume an error to begin with. */
  165.  
  166.         bError = TRUE;
  167.  
  168.         if ( FileSpec.fullName[0] == '\0' ) /* No file name on command line */
  169.         {
  170.         lstrcpy( (LPSTR) szString, "No file name specified." );
  171.         }
  172.         else if ( !GetExtFilter( ) ) /* Unable to find filter */
  173.         {
  174.         lstrcpy( (LPSTR) szString, 
  175.             "No filter specified in WIN.INI for file extension." );
  176.         }
  177.         else if ( !ImportFile( hWnd ) ) /* Unable to import */
  178.         {
  179.         lstrcpy( (LPSTR) szString, "Unable to import file." );
  180.         }   
  181.         else bError = FALSE;  /* Import was a success */
  182.  
  183.         if (bError) 
  184.         {
  185.         MessageBox( hWnd, (LPSTR) szString, 
  186.                       (LPSTR) szAppName,
  187.                       MB_OK | MB_ICONHAND );
  188.         DestroyWindow( hWnd );
  189.         }
  190.         break;
  191.     
  192.  
  193.     case WM_PAINT:     /* Paint window by playing metafile. */
  194.  
  195.         if ( PictInfo.hmf ) /* A file has been imported. */
  196.         {
  197.             PAINTSTRUCT     ps;
  198.             HDC             hDC = BeginPaint( hWnd, &ps );
  199.  
  200.             SetMapMode( hDC, MM_ANISOTROPIC );
  201.             SetWindowExt( hDC, PictInfo.bbox.right - PictInfo.bbox.left,
  202.                        PictInfo.bbox.bottom - PictInfo.bbox.top );
  203.             GetClientRect( hWnd, &rc );
  204.             SetViewportExt( hDC, rc.right - rc.left, rc.bottom - rc.top );
  205.  
  206.             SetWindowOrg( hDC, PictInfo.bbox.left, PictInfo.bbox.top );
  207.             PlayMetaFile( hDC, PictInfo.hmf );
  208.  
  209.             EndPaint( hWnd, &ps );
  210.         }
  211.         break;
  212.  
  213.     case WM_SIZE:  /* Invalidate, and paint full window. */
  214.  
  215.         GetClientRect( hWnd, &rc );
  216.         InvalidateRect( hWnd, &rc, TRUE);
  217.         UpdateWindow( hWnd );
  218.         break;
  219.  
  220.     case WM_DESTROY:  /* Send WM_QUIT message to message loop to end. */
  221.  
  222.         PostQuitMessage( hWnd );
  223.         break;
  224.  
  225.     case WM_COMMAND:  /* Creates About dialog box. */
  226.        
  227.         if ( wParam == IDM_ABOUT )
  228.         {
  229.             lpProc = MakeProcInstance( AboutDlgProc, hInst );
  230.  
  231.             DialogBox( hInst, "AboutBox", hWnd, lpProc );
  232.         
  233.             FreeProcInstance( lpProc );
  234.             
  235.             break;
  236.         }  /* Otherwise, fall through to default. */
  237.  
  238.     default:
  239.               
  240.         return ( DefWindowProc( hWnd, message, wParam, lParam ) );
  241.     }
  242.     return (NULL);
  243. }
  244.  
  245. /***************************************************************************
  246. *                                                                          *
  247. *       FUNCTION: ImportFile                                               *
  248. *       PURPOSE : Translate a graphic file to a metafile using a filter    *
  249. *                                                                          *
  250. *       ARGS    : HWND hWnd - handle to main window.                       *
  251. *       RETURN  : TRUE if file import is successful, otherwise FALSE.      *
  252. *                                                                          *
  253. *       COMMENTS: Loads a filter DLL into memory, and uses it's import     *
  254. *                 functionality to translate a graphic file to a metafile. *
  255. *                 Uses Aldus-standard interface functions, version 1 or 2. *
  256. *                                                                          *
  257. ***************************************************************************/
  258.  
  259. BOOL NEAR ImportFile(HWND hWnd)
  260. {
  261.     HANDLE          hFilter = NULL, hPrefMem = NULL;
  262.     WORD            wFilterResult = -1;
  263.     HDC             hPrintIC = NULL;
  264.  
  265. /* Version 1.0 Filter functions */
  266.  
  267.     PFN_INFO        lpfnGetFilterInfo = NULL;
  268.     PFN_IMPORT      lpfnImportGR = NULL;
  269.     PFN_PREF        lpfnGetFilterPref = NULL;
  270.  
  271. /* Version 2.0 Filter functions */
  272.  
  273.     PFN_VER         lpfnGetFilterVersion = NULL;
  274.     PFN_ISMY        lpfnIsThisMyFile = NULL;
  275.     PFN_PREF2       lpfnGetFilterPref2 = NULL;
  276.     PFN_OUTPUT      lpfnOutputGR = NULL;
  277.  
  278. /* Load appropriate filter. */
  279.  
  280.     hFilter = LoadLibrary( (LPSTR) szFilter );
  281.  
  282. /* Try to find "GetFilterVersion." */
  283.  
  284.     lpfnGetFilterVersion = GetProcAddress( hFilter, 
  285.                      "GetFilterVersion" );
  286.  
  287.     if ( !lpfnGetFilterVersion ) /* This is a v 1.0 filter. */
  288.     {
  289.  
  290.         lpfnGetFilterInfo = GetProcAddress( hFilter, 
  291.                         "GetFilterInfo" );
  292.  
  293.         if ( lpfnGetFilterInfo )
  294.         {
  295.             wFilterResult = (*lpfnGetFilterInfo)( 2, 
  296.                         NULL, 
  297.                         &hPrefMem, 
  298.                         NULL );
  299.         } 
  300.  
  301. /* Call filter's GetFilterPref function, which creates a "filter preference"
  302. ** dialog box to set import options. */
  303.  
  304.         lpfnGetFilterPref = GetProcAddress( hFilter, 
  305.                         "GetFilterPref" );
  306.  
  307.         if ( lpfnGetFilterPref )
  308.         {   
  309.             (*lpfnGetFilterPref)( hInst, hWnd, hPrefMem, 1 );
  310.         }
  311.  
  312. /* Call filter's ImportGR function to convert the file to a Windows
  313. ** metafile (information is stored in FileSpec). */
  314.  
  315.  
  316.         lpfnImportGR = GetProcAddress( hFilter, "ImportGR" );
  317.         if ( lpfnImportGR )
  318.         {
  319.             hPrintIC = GetPrinterIC();
  320.  
  321.             wFilterResult = (*lpfnImportGR)( hPrintIC, 
  322.                              &FileSpec, 
  323.                              &PictInfo, 
  324.                              hPrefMem );
  325.         }
  326.     }
  327.     
  328.     else /* This is a v. 2.0 or higher filter. */
  329.     {
  330.  
  331. /* Ensure that current file is compatible with current filter. */
  332.  
  333.         lpfnIsThisMyFile = GetProcAddress( hFilter, 
  334.                         "IsThisMyFile" );
  335.         
  336.         if ( lpfnIsThisMyFile )
  337.         {
  338.  
  339.             (*lpfnIsThisMyFile) ( &FileSpec );
  340.  
  341.         }
  342.  
  343. /* Get user's import preferences. */
  344.  
  345.         lpfnGetFilterPref2 = GetProcAddress( hFilter, "GetFilterPref" );
  346.         if (lpfnGetFilterPref2)
  347.         {
  348.             wFilterResult = (*lpfnGetFilterPref2) ( hInst,
  349.                                hWnd,
  350.                                &hPrefMem,
  351.                                FileSpec.fType,
  352.                                NULL,
  353.                                &FileSpec);
  354.         }
  355. /* Convert chosen file to a metafile. */
  356.  
  357.         lpfnOutputGR = GetProcAddress( hFilter, "OutputGR" );
  358.         if (lpfnOutputGR)
  359.         {
  360.             hPrintIC = GetPrinterIC();
  361.  
  362.             wFilterResult = (*lpfnOutputGR) ( NULL,
  363.                             hPrintIC,
  364.                             &FileSpec,
  365.                             NULL,
  366.                             &PictInfo,
  367.                             hPrefMem,
  368.                             NULL,
  369.                             FALSE);
  370.         }
  371.     }
  372.  
  373. /* Free the memory allocated to the filter DLL and the preference memory.*/
  374.  
  375.     FreeLibrary( hFilter );
  376.     GlobalFree( hPrefMem );
  377.  
  378. /* Set the window title to the file name, or return false. */
  379.  
  380.     if ( wFilterResult == 0 ) 
  381.     {
  382.         SetWindowText( hWnd, FileSpec.fullName );
  383.         return TRUE;
  384.     }
  385.     else
  386.     {
  387.         return FALSE;
  388.     }
  389. }
  390.  
  391. /***************************************************************************
  392. *                                                                          *
  393. *       FUNCTION: GetExtFilter                                             *
  394. *       PURPOSE : Get filename of filter appropriate for current file.     *
  395. *                                                                          *
  396. *       ARGS    : none                                                     *
  397. *       RETURN  : TRUE if able to find filter, otherwise FALSE.            *
  398. *                                                                          *
  399. *       COMMENTS: Gets all filter names listed under [GraphicViewer]       *
  400. *                 heading in WIN.INI.  Checks which one entry supports     *
  401. *                 files with the same extension as FileSpec.fullName.      *
  402. *                                                                          *
  403. ***************************************************************************/
  404.  
  405. BOOL NEAR GetExtFilter( void )
  406. {
  407.     PSTR pDesc, pExt, pSupExt;
  408.     int  nLen = lstrlen( FileSpec.fullName );
  409.  
  410.     /* Set pExt to last char in FileSpec.fullName. */
  411.  
  412.     if (!nLen) return FALSE;
  413.  
  414.     pExt = FileSpec.fullName + nLen - 1; 
  415.  
  416.     /* decrement to character after period ('.'). */
  417.  
  418.     while ( *(pExt-1) != '.' )  
  419.     {
  420.         pExt--;
  421.         if ( pExt == FileSpec.fullName ) return FALSE;
  422.     }
  423.  
  424.     /* get all profile string entries (description of filter). */
  425.  
  426.     nLen = GetProfileString( szAppName, NULL, NULL, szString, STRINGSIZE );
  427.  
  428.     /* start with the first description. */
  429.     
  430.     pDesc = szString;
  431.  
  432.     /* while we still have a string to check... */
  433.  
  434.     while ( pDesc < szString + nLen )
  435.     {
  436.         /* get the entry for this filter
  437.         ("[filter file name],[ext]") */
  438.  
  439.         GetProfileString( (LPSTR) szAppName, (LPSTR) pDesc, 
  440.                   NULL, (LPSTR) szFilter, IBMFNSIZE );
  441.         
  442.         /* if one exists, and its extension matches the file
  443.         ** extension... */
  444.  
  445.         pSupExt = szFilter + lstrlen( (LPSTR) szFilter) - 1;
  446.  
  447.         while ( *( pSupExt - 1 ) != ',' )
  448.         {
  449.             pSupExt--;
  450.             if (pSupExt == szFilter) return FALSE;
  451.         }
  452.  
  453.         if( lstrcmpi( (LPSTR) pExt, (LPSTR) pSupExt ) == 0 )
  454.         {
  455.             *(pSupExt-1) = '\0'; 
  456.             return TRUE;
  457.         }
  458.         else
  459.         {
  460.                /* move on to next filter. */
  461.                pDesc += lstrlen( (LPSTR) pDesc ) + 1;
  462.         }
  463.     }
  464.  
  465.     /* if we get here, we couldn't find one. Make sure szFilter is blank.*/
  466.     
  467.     szFilter[0] = '\0';
  468.  
  469.     /* Report failure. */
  470.  
  471.     return FALSE;
  472. }
  473.  
  474. /***************************************************************************
  475. *                                                                          *
  476. *       FUNCTION: GetPrinterIC                                             *
  477. *       PURPOSE : Get information context for active print device.         *
  478. *                                                                          *
  479. *       ARGS    : none                                                     *
  480. *       RETURN  : handle to printer's information context or NULL if fail. *
  481. *                                                                          *
  482. *       COMMENTS: Gets device description from [windows] heading in        *
  483. *                 WIN.INI.  Breaks down the description into device name,  *
  484. *                 driver name, and output port.  Uses CreateIC() to get    *
  485. *                 an information context.                                  *
  486. *                                                                          *
  487. ***************************************************************************/
  488.  
  489. HDC GetPrinterIC( void )
  490. {
  491.     int  nLen;
  492.     PSTR pDevice, pDriver, pOutput;
  493.     HDC  hPrintIC = NULL;
  494.     
  495. /* Get the information on the current printer, listed under "windows" in
  496. ** WIN.INI as "device=[device name],[driver],[output port]". */
  497.  
  498.     nLen = GetProfileString("windows", "device", NULL,
  499.                     (LPSTR) szString, STRINGSIZE);
  500.  
  501. /* Break it down into device name, driver name, output port. */
  502.  
  503.     if ( nLen )
  504.     {
  505.     /* The device name is the beginning of the string. */
  506.  
  507.         pDevice = szString;
  508.  
  509.     /* The driver name comes right after the first comma ','. */
  510.  
  511.         pDriver = szString;
  512.  
  513.         while ( ( *pDriver != ',' ) )
  514.         {
  515.              pDriver++;
  516.              if ( pDriver >= szString + nLen ) return NULL;
  517.         }        
  518.  
  519.         *pDriver = '\0';        pDriver++;
  520.  
  521.     /* The output port name comes right after the second comma ','. */
  522.  
  523.         pOutput = pDriver;
  524.  
  525.         while ( ( *pOutput != ',' ) )
  526.         {
  527.              pOutput++;
  528.              if ( pOutput >= szString + nLen ) return NULL;
  529.         }        
  530.  
  531.         *pOutput = '\0';        pOutput++;
  532.  
  533.     /* Create an information context for this device. */
  534.  
  535.         hPrintIC = CreateIC( (LPSTR) pDriver, (LPSTR) pDevice,
  536.                     (LPSTR) pOutput, NULL );
  537.     }
  538.  
  539.     return ( hPrintIC ); 
  540. }
  541.  
  542. /***************************************************************************
  543. *                                                                          *
  544. *       FUNCTION: AboutDlgProc                                             *
  545. *       PURPOSE : Handles messages for AboutBox dialog box.                *
  546. *                                                                          *
  547. *       ARGS    : Standard callback arguments.                             *
  548. *       RETURN  : N/A.                                                     *
  549. *                                                                          *
  550. *       COMMENTS: Closes AboutBox when OK button, Enter or ESC are pressed.*
  551. *                                                                          *
  552. ***************************************************************************/
  553.  
  554.  
  555. BOOL FAR PASCAL AboutDlgProc(HWND hDlg, unsigned message, 
  556.                 WORD wParam, LONG lParam)
  557. {
  558.     switch (message) 
  559.     {
  560.     case WM_INITDIALOG:  /* Beginning. No functionality. */              
  561.         
  562.         return (TRUE);
  563.  
  564.     case WM_COMMAND:
  565.               
  566.         switch (wParam)
  567.         {
  568.             case IDOK:  /* OK or Enter were pressed. */              
  569.             case IDCANCEL: /* Esc was pressed. */
  570.         
  571.                 EndDialog(hDlg, TRUE);        
  572.                 return (TRUE);
  573.         }
  574.         break;
  575.     }
  576.     return (FALSE);                           
  577. }
  578.  
  579.